package pw.goyd.db;

import pw.goyd.game.constant.setting.ServerSetting;
import pw.goyd.game.server.Log;
import pw.goyd.subscribe.Publisher;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException;

/**
 * Jedis池管理 和 订阅
 *
 * @author StanWind
 */
public final class RedisUtil implements ServerSetting {
    private static JedisPool jedisPool = null;  //  Redis Client Pool
    private static Publisher pub = null;        //  Publisher


    /**
     * 初始化Redis连接池
     */
    /**
     static {
     init();
     }
     */
    /**
     * init
     */
    public static void init() {
        try {
            JedisPoolConfig config = new JedisPoolConfig(); // ConfigPool
            config.setMaxActive(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWait(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);
            //无密码
            //jedisPool = new JedisPool(config, R_ADDR, R_PORT, TIMEOUT);
            jedisPool = new JedisPool(config, R_ADDR, R_PORT, TIMEOUT, R_AUTH); //  有密码


            //订阅 获取客户端
            pub = new Publisher();   // Publisher
            pub.publish(getJedis()); // 发布一个频道

        } catch (Exception e) {
            Log.getLogger().error("JedisInitError", e);
        }
    }

//    /**
//     * 获取JedisPool 用来新建Jedis对象
//     * @return JedisPool
//     */
//    private static JedisPool getJedisPool(){
//    	return jedisPool;
//    }

    /**
     * 发布消息
     */
    public static void publishData(final byte[] channel, final byte[] data) {
        Jedis j = getJedis();
        if (j != null) {
            pub.publish(j, channel, data);
            returnResource(j);  //  释放资源
        } else {
            Log.getLogger().error("Jedis对象不足");
        }
    }

    /**
     * 推送房间消息
     *
     * @param roomID 房间号
     * @param data   推送数据
     */
    public static void pubRoom(final int roomID, final byte[] data) {
        Jedis j = getJedis();
        if (j != null) {
            pub.publish(j, ("room." + roomID).getBytes(), data);
            returnResource(j);  //  释放资源
        } else {
            Log.getLogger().error("Jedis对象不足");

        }
    }


    /**
     * 获取Jedis实例
     *
     * @return Jedis对象
     */
    public synchronized static Jedis getJedis() {
        int timeoutCount = 0;
        while (true) {
            try {
                if (null != jedisPool) {
                    return jedisPool.getResource();
                }
            } catch (Exception e) {
                if (e instanceof JedisConnectionException) {
                    timeoutCount++;
                    Log.getLogger().warn("getJedis timeoutCount={}", timeoutCount);
                    if (timeoutCount > 3) {
                        break;
                    }
                } else {
                    Log.getLogger().error("GetJedis error,", e);
                    break;
                }
            }
            break;
        }
        return null;
    }

    /**
     * 释放jedis资源
     *
     * @param jedis Jedis对象
     */
    public static void returnResource(final Jedis jedis) {
        if (jedis != null) {
            jedisPool.returnResource(jedis);
        }
    }
}